// Map vars
var map;
var points              = [];
var pointNumbers        = 0;
var defaultZoom         = 17;
var directionsService   = new google.maps.DirectionsService();
var waiting             = false;
var iconBase            = '/images/maps/';
var firstPosMarker      = false;
var centered            = false;
// Relative to franjas
var totalFranjasPerView = 3;
var currentFranjaStep   = false;
var totalFranjas        = false;
var totalFranjasSteps   = false;
// Relative to path
var route;
var routePath;
var lastPathLengths = Array();
var routePointsRaw  = Array();
// Relative to control points
var controlPoints              = [];
var infoBubblesByControlPoints = Array();
var controlPointsMarkers       = [];
// Other vars
var drawing = false;
var marking = false;
// Map is ready
function initialize()
{
    // Hide POIS
    var noPoi = [
    {
        featureType: "poi",
        stylers: [
          { visibility: "off" }
        ]
      }
    ];
    // Map options
    var mapOptions =
    {
        zoom                   : defaultZoom,
        mapTypeId              : google.maps.MapTypeId.ROADMAP,
        disableDoubleClickZoom : true,
        scrollwheel            : false,
        mapTypeControl         : false,
        panControl             : false,
        rotateControl          : false
    };
    map = new google.maps.Map(document.getElementById('nuevo_recorrido_mapa'),mapOptions);
    map.setOptions({styles: noPoi});
    // Routes
    route = new google.maps.Polyline({
        strokeColor   : '#327e04',
        strokeOpacity : 0.8,
        strokeWeight  : 10
    });
    route.setMap(map);
    routePath = route.getPath();
    noWaiting();
    preloadedRoute();
    // Define click listeners
    google.maps.event.addListener(map, 'click',
        function(event)
        {
            if (!waiting)
            {
                if (drawing)
                {
                    // Build request to snap to street
                    var request =
                    {
                        origin       : event.latLng,
                        destination  : event.latLng,
                        travelMode   : google.maps.DirectionsTravelMode.WALKING
                    };
                    // Get route
                    directionsService.route(request,
                        function(response, status)
                        {
                            if (status == google.maps.DirectionsStatus.OK)
                            {
                                getNextPoint();
                                var lat = response.routes[0].legs[0].start_location.lat();
                                var lng = response.routes[0].legs[0].start_location.lng();
                                points.push({'lat':lat, 'long':lng, 'num':pointNumbers-1});
                                if (points.length > 1)
                                {
                                    calcRoute(pointNumbers-1);
                                }
                                else
                                {
                                    var firstPoint = new google.maps.LatLng(lat, lng);
                                    addPoint(firstPoint, true);
                                }
                            }
                        }
                    );
                }
            }
            else
            {
                notice("Cargando punto. Intente nuevamente");
            }
        }
    );
    // Route Click
    google.maps.event.addListener(route,"click",
        function(event)
        {
            if (!drawing && marking)
            {
                addPoint(event.latLng);
            }
        }
    );
    // Try HTML5 geolocation
    if(navigator.geolocation)
    {
        navigator.geolocation.getCurrentPosition
        (
            function(position)
            {
                if (!centered)
                {
                    var pos = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
                    map.setCenter(pos);
                }
            },
            function()
            {
                handleNoGeolocation(true);
            }
        );
    }
    else
    {
        // Browser doesn't support Geolocation
        handleNoGeolocation(false);
    }
}

// In case GEOLocation is disabled set default
function handleNoGeolocation(errorFlag)
{
    if (errorFlag)
    {
        var content = 'Error: The Geolocation service failed.';
    }
    else
    {
        var content = 'Error: Your browser doesn\'t support geolocation.';
    }
    var options =
    {
        map      : map,
        position : new google.maps.LatLng(60, 105),
        content  : content
    };
    var infowindow = new google.maps.InfoWindow(options);
    map.setCenter(options.position);
}

// New point
function getNextPoint()
{
    return ++pointNumbers;
}

// Build route from new point
function calcRoute(toPointNumber)
{
    var pointOrg  = new google.maps.LatLng(points[toPointNumber-1]['lat'], points[toPointNumber-1]['long']);
    var pointDest = new google.maps.LatLng(points[toPointNumber]['lat'], points[toPointNumber]['long']);
    var request =
    {
        origin      : pointOrg,
        destination : pointDest,
        travelMode  : google.maps.DirectionsTravelMode.WALKING
    };
    isWaiting();
    directionsService.route(request,
        function(response, status)
        {
            if (status == google.maps.DirectionsStatus.OK)
            {
                lastPathLengths.push(routePath.length);
                var myRoute = response.routes[0].legs[0];
                for (var i = 0; i < myRoute.steps.length; i++)
                {
                    for (var j = 0; j < myRoute.steps[i].lat_lngs.length; j++)
                    {
                        routePath.push(myRoute.steps[i].lat_lngs[j]);
                        routePointsRaw.push({'lat':myRoute.steps[i].lat_lngs[j].lat(),'lng':myRoute.steps[i].lat_lngs[j].lng()});
                    }
                }
                noWaiting();
            }
            else
            {
                notice("Error cargando punto. Intente nuevamente.");
                noWaiting();
                pointNumbers--;
            }
        }
    );
}

// Waiting for point append
function isWaiting()
{
    waiting = true;
    $('#mapa_loader').show();
}

function noWaiting()
{
    waiting = false;
    $('#mapa_loader').hide();
}

// Undo
function performUndo()
{
    if (lastPathLengths.length > 0)
    {
        var lpLength = lastPathLengths.pop();
        for (i=routePath.length;i>lpLength;i--)
        {
            routePath.pop();
            routePointsRaw.pop();
        }
        points.pop();
        pointNumbers--;
    }
    else
    {
        controlPoints        = Array();
        points               = Array();
        controlPointsMarkers = Array();
        pointNumbers         = 0;
        firstPosMarker.setMap(null);
        infoBubblesByControlPoints[0].close();
        infoBubblesByControlPoints = Array();
        $('#recorrido_puntos_order').empty();
    }
}

// Control point info
function returnControlPointInfo(content)
{
    var i = new InfoBubble({
        content          : '<div style="color:#FFFFFF; text-align:center; font-weight:bold;">'+content+'</div>',
        shadowStyle      : 0,
        padding          : 3,
        backgroundColor  : '#459e00',
        borderRadius     : 4,
        arrowSize        : 10,
        borderWidth      : 1,
        borderColor      : '#327E04',
        disableAutoPan   : true,
        hideCloseButton  : true,
        arrowStyle       : 0
    });
    return i;
}

// Point added
function addPoint(latLng, first, preloaded)
{
    // Map
    var pointControl = (controlPoints.length)+1;
    controlPoints.push(latLng);
    if ((first == undefined) || (first == false))
    {
        var markerImage = new google.maps.MarkerImage(iconBase + 'flag_icon.png', new google.maps.Size(38, 38), new google.maps.Point(0, 0), new google.maps.Point(5, 38));
        var marker = new google.maps.Marker(
        {
            position : latLng,
            map      : map,
            icon     : markerImage
        });
        title = "Punto "+pointControl;
        controlPointsMarkers[controlPoints.length - 1] = marker;
    }
    else
    {
        var marker = new google.maps.Marker(
        {
            position : latLng,
            map      : map,
            title    : "- INICIO -<br/>Punto 1",
            icon     : iconBase + 'bus_icon.png',
        });
        title = marker.title;
        firstPosMarker = marker;
        controlPointsMarkers[0] = marker;
    }
    // Info bubbles
    infoBubblesByControlPoints[pointControl-1] = returnControlPointInfo(title);
    infoBubblesByControlPoints[pointControl-1].open(map, marker);
    // Order
    if ((first == undefined) || (first == false))
    {

        $('#recorrido_puntos_order').append(getPointHtml(pointControl));
    }
    else
    {
        $('#recorrido_puntos_order').append(getPointHtml(pointControl, true));
    }
    // Point relations
    if (pointControl > 1)
    {
        var clone = $('#relation_default_foo').clone(true);
        clone.attr('id', 'relation_point_'+(pointControl));
        clone.attr('org', pointControl-1);
        clone.attr('dest', pointControl);
        clone.find('.point_org').html('Punto '+(pointControl-1));
        clone.find('.point_dest').html('Punto '+(pointControl));
        clone.show();
        $('#relaciones_puntos').append(clone);
        clone.find('.point_time_value').timespinner( { step : 1 ,page : 60, min  : 10 } );
        clone.find('.point_time_value').on( "timespinnerstop",
            function(event, ui)
            {
                var val = $(this).val();
                $(this).parent().parent().parent().find('.point_time_value_franja.ui-state-disabled').val(val);
            }
        );
        clone.find('.point_time_value_franja').timespinner( { step : 1 ,page : 60, min  : 10 } );
        clone.find('.point_time_value_franja').on( "timespinnerspin",
            function(event, ui)
            {
                var val = $(this).val();
                if ($(this).hasClass('ui-state-disabled'))
                {
                    $(this).attr('default_tsval', val);
                    $(this).removeClass('ui-state-disabled')
                }
            }
        );
        clone.find('.point_time_value_franja').on( "timespinnerstop",
            function(event, ui)
            {
                var val = $(this).val();
                if (val == $(this).attr('default_tsval'))
                {
                    $(this).addClass('ui-state-disabled')
                }
            }
        );
        if ((preloaded == undefined) || (preloaded == false))
        {
            isWaiting();
            timeBetweenPoints(pointControl-2, pointControl-1, clone.find('.point_time_value, .point_time_value_franja'));
            adjustFranjaToCurrentStep();
        }
        else
        {
            clone.find('.point_label_value').val(preloaded['nombre']);
            clone.find('.point_time_value, .point_time_value_franja').val(getTimeFromSeconds(preloaded['segundosAnterior']));
            clone.find('.point_time_value, .point_time_value_franja').next().val(preloaded['segundosAnterior']);
            clone.find('.point_time_value, .point_time_value_franja').attr('distance', preloaded['distanciaAnterior']);
            clone.find('.franjas_container_foo').attr('id', 'franjas_punto_'+preloaded['idPunto']);
        }
    }
}

// After sorting points
function reorderControlPoints()
{
    // Clone
    var references        = Array();
    var auxControlPoints  = controlPoints.slice();
    var auxControlMarkers = controlPointsMarkers.slice();
    var auxInfoBubbles    = infoBubblesByControlPoints.slice();
    for (i=1;i<infoBubblesByControlPoints.length;i++)
    {
        infoBubblesByControlPoints[i].close();
    }
    // Reset
    controlPoints                 = Array();
    infoBubblesByControlPoints    = Array();
    controlPointsMarkers          = Array();
    controlPoints[0]              = auxControlPoints[0];
    infoBubblesByControlPoints[0] = auxInfoBubbles[0];
    controlPointsMarkers[0]       = auxControlMarkers[0];
    // Sort
    var sorting = $('#recorrido_puntos_order').sortable( "toArray" );
    for (newPos=0;newPos<sorting.length;newPos++)
    {
        // Positions
        var pos = newPos+1;
        var old = ((sorting[newPos].replace('control_point_', ''))*1)-1;
        references.push((old+1));
        // Set
        controlPoints[pos]              = auxControlPoints[old];
        controlPointsMarkers[pos]       = auxControlMarkers[old];
        infoBubblesByControlPoints[pos] = returnControlPointInfo("Punto "+(pos+1));
        infoBubblesByControlPoints[pos].open(map, controlPointsMarkers[pos]);
    }
    // Update each point in map
    $('#recorrido_puntos_order').children('.point_change').remove();
    for (i=1;i<controlPoints.length;i++)
    {
        pointControl = i+1;
        $('#recorrido_puntos_order').append(getPointHtml(pointControl)).fadeIn('fast');
    }
    // Reorder times list and recalculate suggested times
    reorderTimesListAndRecalculate(references);
}

// Reorder times list after points order change
function reorderTimesListAndRecalculate(references)
{
    // Save aux old origins
    var auxTimes = Array();
    for (i=0; i<$('.route_point:not(#relation_default_foo)').length;i++)
    {
        var obj  = $('#relation_point_'+(i+2));
        var org  = (obj.attr('org'))*1;
        var dest = (obj.attr('dest'))*1;
        auxTimes[i] = {'org':org, 'dest':dest};
    }
    // Sort list
    var newPointsOrder = Array();
    for (i=0;i<references.length;i++)
    {
        var point = $('.route_point[dest="'+references[i]+'"]').detach();
        point.attr('id', 'relation_point_'+(i+2));
        newPointsOrder[i] = point;
    }
    for (i=0;i<newPointsOrder.length;i++)
    {
        newPointsOrder[i].appendTo('#relaciones_puntos');
    }
    for (i=0; i<$('.route_point:not(#relation_default_foo)').length;i++)
    {
        var obj     = $('#relation_point_'+(i+2));
        var newDest = obj.attr('dest')*1;
        if (i==0)
        {
            var newOrg = 1;
        }
        else
        {
            var newOrg = (obj.prev().attr('dest'))*1;
        }
        var oldOrg = (obj.attr('org'))*1;
        if (oldOrg != newOrg)
        {
            obj.find('.point_time_value').val('');
            obj.find('.point_time_value_franja').val('').addClass('ui-state-disabled');
            isWaiting();
            timeBetweenPoints(i, i+1, obj.find('.point_time_value, .point_time_value_franja'));
        }
        else
        {

        }
        obj.attr('dest', i+2);
        obj.attr('org', i+1);
        obj.find('.point_org').html('Punto '+(i+1));
        obj.find('.point_dest').html('Punto '+(i+2));
    }
}

// Retrieve point HTML to list
function getPointHtml(pointControl, isFirst)
{
    if (isFirst != undefined)
    {
        var html = '<li id="control_point_'+pointControl+'" pointNumber="'+pointControl+'" class="point ui-state-disabled">INICIO - Punto '+pointControl+'</li>'
    }
    else
    {
        var html = '<li id="control_point_'+pointControl+'" pointNumber="'+pointControl+'" class="point point_change ui-state-default">Punto '+pointControl+'<div class="delete_point ui-icon ui-icon-circle-close" pointNumber="'+pointControl+'" onClick="removeControlPoint('+pointControl+')"></div></li>';
    }
    return html;
}

// Delete control point
function removeControlPoint(pointNumber)
{
    if (pointNumber > 0)
    {
        $('#relation_point_'+pointNumber).remove();
        controlPointsMarkers[pointNumber-1].setMap(null);
        var firstInfoBubble = infoBubblesByControlPoints[0];
        for (i=1;i<infoBubblesByControlPoints.length;i++)
        {
            infoBubblesByControlPoints[i].close();
        }
        for (i=(pointNumber-1);i<(controlPoints.length-1);i++)
        {
            controlPointsMarkers[i] = controlPointsMarkers[i+1];
            controlPoints[i]        = controlPoints[i+1];
        }
        controlPointsMarkers.remove(i);
        controlPoints.remove(i);
        infoBubblesByControlPoints.remove(i);
        // Update each point
        $('#recorrido_puntos_order').children('.point_change').remove();
        infoBubblesByControlPoints = Array();
        infoBubblesByControlPoints[0] = firstInfoBubble;
        for (i=1;i<controlPoints.length;i++)
        {
            pointControl = i+1;
            $('#recorrido_puntos_order').append(getPointHtml(pointControl)).fadeIn('fast');
            infoBubblesByControlPoints[i] = returnControlPointInfo("Punto "+(i+1));
            infoBubblesByControlPoints[i].open(map, controlPointsMarkers[i]);
        }
        recalculateTimeAndPositionInRelations(pointNumber);
    }
}

// Recalculate time and positions
function recalculateTimeAndPositionInRelations(pointNumber)
{
    if (pointNumber <= controlPoints.length)
    {
        for (pointControl = pointNumber; pointControl<=controlPoints.length; pointControl++)
        {
            var obj = $('#relation_point_'+(pointControl+1));
            obj.attr('id', 'relation_point_'+pointControl);
            obj.attr('org', pointControl-1);
            obj.attr('dest', pointControl);
            obj.find('.point_org').html('Punto '+(pointControl-1));
            obj.find('.point_dest').html('Punto '+(pointControl));
            if (pointControl == pointNumber)
            {
                obj.find('.point_time_value').val('');
                obj.find('.point_time_value_franja').val('').addClass('ui-state-disabled');
                isWaiting();
                timeBetweenPoints(pointControl-2, pointControl-1, obj.find('.point_time_value, .point_time_value_franja'));
            }
        }
    }
}

// Request google suggested time between two points
function timeBetweenPoints(from, to, object)
{
    if ((controlPoints[from] != undefined) && (controlPoints[to] != undefined))
    {
        // Build request to snap to street
        var request =
        {
            origin       : controlPoints[from],
            destination  : controlPoints[to],
            travelMode   : google.maps.DirectionsTravelMode.DRIVING
        };
        // Get route
        directionsService.route(request,
            function(response, status)
            {
                if (status == google.maps.DirectionsStatus.OK)
                {
                    object.val(getTimeFromSeconds(response.routes[0].legs[0].duration.value));
                    object.next().val(response.routes[0].legs[0].duration.value);
                    object.attr('distance', response.routes[0].legs[0].distance.value);
                }
                else
                {
                    object.val('');
                }
                noWaiting();
            }
        );
    }
}

// Jquery goodness
$(function(){
    $('#button_examinar').button( { icons: { primary: "ui-icon-arrow-4-diag" } } ).bind('click', function(){
        drawing = false;
        marking = false;
        map.setOptions({draggableCursor:'pointer'});
        $('#button_dibujar').show();
        $('#button_undo_route').hide();
    });
    $('#button_dibujar').button( { icons: { primary: "ui-icon-pencil" } } ).bind('click', function(){
        drawing = true;
        marking = false;
        map.setOptions({ draggableCursor: 'url('+iconBase + 'pencil_icon.png'+'), pointer' });
        $('#button_dibujar').hide();
        $('#button_undo_route').show();
    });
    $('#button_marcar').button( { icons: { primary: "ui-icon-flag" } } ).bind('click', function(){
        drawing = false;
        marking = true;
        map.setOptions({draggableCursor:'pointer'});
        $('#button_dibujar').show();
        $('#button_undo_route').hide();
    });
    $('#button_save_incomplete').button( { icons: { primary: "ui-icon-document" } } ).bind('click', function(){
        save(true);
    });
    $('.button_save_all').button( { icons: { primary: "ui-icon-disk" } } ).bind('click', function(){
        save();
    });
    $('#button_undo_route').button( { icons: { primary: "ui-icon-arrowreturnthick-1-w" } } ).bind('click', function(){
        if (drawing)
        {
            if (controlPoints.length > 1)
            {
                $("#undo_confirm").dialog({
                    resizable: false,
                    height:240,
                    modal: true,
                    buttons:
                    {
                        "Deshacer ultima linea": function() {
                            $( this ).dialog( "close" );
                            performUndo();
                        },
                        "Cancelar": function() {
                            $( this ).dialog( "close" );
                        }
                    }
                });
            }
            else
            {
                performUndo();
            }
        }
    });
    $('#recorrido_puntos_order').sortable( { items: "li:not(.ui-state-disabled)", update:function() { reorderControlPoints() ; } } );
    // Franjas list
    $('#franja_move_left').button( {icons: { primary: "ui-icon-circle-triangle-w" }, text: false }).bind('click', function(){franjaScrollLeft();});;
    $('#franja_move_right').button( {icons: { primary: "ui-icon-circle-triangle-e" }, text: false }).bind('click', function(){franjaScrollRight();});;
    prepareFranjasScroll();
});

function prepareFranjasScroll()
{
    totalFranjas      = $('#franjas_container_foo').children().length;
    totalFranjasStep  = Math.ceil(totalFranjas/totalFranjasPerView);
    currentFranjaStep = 0;
    franjaScrollRight();
}

function franjaScrollLeft()
{
    if (currentFranjaStep > 1)
    {
        currentFranjaStep--;
    }
    else
    {
        currentFranjaStep = totalFranjasStep;
    }
    adjustFranjaToCurrentStep();
}

function franjaScrollRight()
{
    if (currentFranjaStep < totalFranjasStep)
    {
        currentFranjaStep++;
    }
    else
    {
        currentFranjaStep = 1;
    }
    adjustFranjaToCurrentStep();
}

function adjustFranjaToCurrentStep()
{
    $('.franja_reference').hide();
    $('.route_point:visible').children('.franjas_list').children('.franjas_container_foo').children('.point_time_franja_value_container').hide();
    var from = (currentFranjaStep-1)*totalFranjasPerView;
    for(i=from;i<=from+2;i++)
    {
        $('.franja_reference:eq('+i+')').show();
    }
    $('.route_point:visible').each(function(){
        var o = $(this).children('.franjas_list').children('.franjas_container_foo');
        for(i=from;i<=from+2;i++)
        {
            o.children('.point_time_franja_value_container:eq('+i+')').show();
        }
    });
}

function save(incomplete)
{
    var validate = (incomplete != undefined)?false:true;
    var name = $('#nombre_recorrido').val();
    var errList = Array();
    if (name == '')
    {
        if (incomplete == undefined)
        {
            notice("Para poder guardar una ruta, esta debe poseer un nombre de referencia");
        }
        else
        {
            notice("Para poder guardar una ruta provisoriamente, esta debe poseer al menos un nombre de referencia");
        }
    }
    else
    {
        $('.appended_form_element').remove();
        // Save type?
        if (incomplete != undefined)
        {
            $('#hidden_save_form').append('<input type="hidden" name="ruta[incomplete]" value="1" class="appended_form_element" />');
        }
        // Assign nombre
        $('#ruta_nombre').val(name);
        // Camino - puntos
        var pathIndex = 0;
        var pathPoint = 0;
        for (i=0;i<routePointsRaw.length;i++)
        {
            // Path split
            if (pathPoint == lastPathLengths[pathIndex+1])
            {
                pathIndex++;
            }
            pathPoint++;
            // Clone
            var fooCaminoPointLat  = $('#foo_punto_camino_lat').clone(true);
            var fooCaminoPointLng  = $('#foo_punto_camino_lng').clone(true);
            var fooCaminoPointPath = $('#foo_punto_camino_path').clone(true);
            // Lat
            fooCaminoPointLat.removeAttr('id');
            fooCaminoPointLat.addClass('appended_form_element');
            fooCaminoPointLat.attr('name', fooCaminoPointLat.attr('name').replace('foo_camino_punto', i));
            fooCaminoPointLat.val(routePointsRaw[i].lat);
            // Lang
            fooCaminoPointLng.removeAttr('id');
            fooCaminoPointLng.addClass('appended_form_element');
            fooCaminoPointLng.attr('name', fooCaminoPointLng.attr('name').replace('foo_camino_punto', i));
            fooCaminoPointLng.val(routePointsRaw[i].lng);
            // Path
            fooCaminoPointPath.removeAttr('id');
            fooCaminoPointPath.addClass('appended_form_element');
            fooCaminoPointPath.attr('name', fooCaminoPointPath.attr('name').replace('foo_camino_punto', i));
            fooCaminoPointPath.val(pathIndex);
            // Append in form
            $('#hidden_save_form').append(fooCaminoPointLat);
            $('#hidden_save_form').append(fooCaminoPointLng);
            $('#hidden_save_form').append(fooCaminoPointPath);
        }
        // Puntos
        for (i=0;i<controlPoints.length;i++)
        {
            // Clone point elements
            var fooPuntoNombre   = $('#punto_foo_nombre').clone(true).removeAttr('id').addClass('appended_form_element');
            var fooPuntoLat      = $('#punto_foo_latitud').clone(true).removeAttr('id').addClass('appended_form_element');
            var fooPuntoLng      = $('#punto_foo_longitud').clone(true).removeAttr('id').addClass('appended_form_element');
            var fooPuntoSeconds  = $('#punto_foo_segundos_anterior').clone(true).removeAttr('id').addClass('appended_form_element');
            var fooPuntoDistance = $('#punto_foo_distancia_anterior').clone(true).removeAttr('id').addClass('appended_form_element');
            var fooPuntoOrder    = $('#punto_foo_orden').clone(true).removeAttr('id').addClass('appended_form_element');
            // First point case
            if (i == 0)
            {
                var latitude  = controlPoints[i].lat();
                var longitude = controlPoints[i].lng();
                fooPuntoNombre.val('INICIO');
                fooPuntoOrder.val(i);
                fooPuntoLat.val(latitude);
                fooPuntoLng.val(longitude);
            }
            // Other points
            else
            {
                // Points relation row
                var container = $('#relation_point_'+(i+1));
                // Get default values
                var name      = container.find('.point_label_value').val();
                var time      = (container.find('.point_time_value').next().val())*1;
                var distance  = (container.find('.point_time_value').attr('distance'))*1;
                var latitude  = controlPoints[i].lat();
                var longitude = controlPoints[i].lng();
                // NonEmpty assigns
                fooPuntoOrder.val(i);
                fooPuntoLat.val(latitude);
                fooPuntoLng.val(longitude);
                // Validations and assignment
                if (incomplete)
                {
                    fooPuntoNombre.val(name);
                    fooPuntoDistance.val(distance);
                    fooPuntoSeconds.val(time);
                }
                else
                {
                    if (name == '') errList.push('Relacion con origen Punto '+i+' y destino Punto '+(i+1)+' debe poseer un nombre');
                    else fooPuntoNombre.val(name);
                    if (time == '') errList.push('Relacion con origen Punto '+i+' y destino Punto '+(i+1)+' debe poseer un tiempo de duracion');
                    else fooPuntoSeconds.val(time);
                    if (distance == '') errList.push('Relacion con origen Punto '+i+' y destino Punto '+(i+1)+' debe poseer una distancia calculada por la API de google maps. Borre el punto y vuelva a intentarlo.');
                    else fooPuntoDistance.val(distance);
                }
            }
            // For all points
            fooPuntoNombre.attr('name', fooPuntoNombre.attr('name').replace('foo_punto', i));
            fooPuntoLat.attr('name', fooPuntoLat.attr('name').replace('foo_punto', i));
            fooPuntoLng.attr('name', fooPuntoLng.attr('name').replace('foo_punto', i));
            fooPuntoDistance.attr('name', fooPuntoDistance.attr('name').replace('foo_punto', i));
            fooPuntoSeconds.attr('name', fooPuntoSeconds.attr('name').replace('foo_punto', i));
            fooPuntoOrder.attr('name', fooPuntoOrder.attr('name').replace('foo_punto', i));
            // Append to form
            $('#hidden_save_form').append(fooPuntoNombre);
            $('#hidden_save_form').append(fooPuntoLat);
            $('#hidden_save_form').append(fooPuntoLng);
            $('#hidden_save_form').append(fooPuntoOrder);
            if (i > 0)
            {
                $('#hidden_save_form').append(fooPuntoDistance);
                $('#hidden_save_form').append(fooPuntoSeconds);
            }
            // Franjas per point
            if (i > 0)
            {
                container.find('.point_time_value_franja').each(function(){
                    var franja = $(this);
                    var myTime = (franja.next().val())*1;
                    if (myTime != time)
                    {
                        var fooFranja = $('#foo_franja_punto').clone(true).removeAttr('id').addClass('appended_form_element');
                        fooFranja.attr('name', fooFranja.attr('name').replace('foo_punto', i));
                        fooFranja.attr('name', fooFranja.attr('name').replace('foo_franja_punto_orden', franja.attr('franja')));
                        fooFranja.val(myTime);
                        $('#hidden_save_form').append(fooFranja);
                    }
                });
            }
        }
        // Check for errors
        if (errList.length > 0)
        {
            notice("<strong>Atencion!</strong><br/><br/>-"+ errList.join('<br/><br/>-'));
        }
        else
        {
            // Save
            isWaiting();
            $.post( guardarRutaAction, $('#hidden_save_form').serialize(), function(data) {
                data = jQuery.parseJSON(data);
                if (data['response'] == 'error')
                {
                    notice(data['msg']);
                }
                else if (data['response'] == 'ok')
                {
                    notice(data['msg']);
                    $('#idruta').val(data['idruta']);
                }
                else
                {
                    notice("Error guardando. Intente nuevamente.");
                }
            })
            .fail(function() { notice("Error guardando. Intente nuevamente."); })
            .always(function() { noWaiting(); });
        }
        return;
    }
}

function drawRouteEdit(num, lat, lng, path)
{
    if (num == 0)
    {
        centered = true;
        var pos = new google.maps.LatLng(lat,lng);
        map.setCenter(pos);
    }
    getNextPoint();
    points.push({'lat':lat, 'long':lng, 'num':pointNumbers-1});
    routePath.push(new google.maps.LatLng(lat,lng));
    routePointsRaw.push({'lat':lat,'lng':lng});
    if (lastPathLengths[path] == undefined)
    {
        lastPathLengths.push(num);
    }
}

var firstPointEdit = true;
function drawPointsEdit(idPunto, lat, lng, nombre, segundosAnterior, distanciaAnterior)
{
    var point = new google.maps.LatLng(lat, lng);
    if (firstPointEdit)
    {
        firstPointEdit = false;
        addPoint(point, true, true);
    }
    else
    {
        var preloadedData = {'idPunto':idPunto, 'nombre':nombre, 'segundosAnterior':segundosAnterior, 'distanciaAnterior':distanciaAnterior}
        addPoint(point, false, preloadedData);
    }
}

function updateFranjaPorPunto(idPunto, idFranja, segundosAnterior)
{
    var franjasContainer = $('#franjas_punto_'+idPunto);
    franjasContainer.find('.point_time_value_franja[franja='+idFranja+']').timespinner( "value", segundosAnterior).removeClass('ui-state-disabled');
}